#include <bex/bex.hpp>
// #ifdef BV_USE_DYN_LOADER
// #include <bex/bex.import.hpp>
// #endif
#include <parse.hpp>
#include <data.hpp>

// 插件名
#define PLUGIN_NAME "ReadData"

// using namespace baltam;

/* 声明插件内实现的函数 */
void getmatrix(int, bxArray*[], int, const bxArray*[]);

/* 帮助文档 */
static const char * getmatrix_help= R"(
getmatrix 从文本文件中读取矩阵.

    A = getmatrix(filename, Name, Value) 语法和 readmatrix 函数相同.
    filename 仅支持字符(串)数组格式输入的绝对路径或相对路径.

    getmatrix 没有实现 readmatrix 的全部功能, 但增加了对 "ConsecutiveDelimitersRule" 和 "LeadingDelimitersRule" 参数的支持.

    Delimiter: 字段分隔符, 默认值为空格 ' '.
    ConsecutiveDelimitersRule: 管理连续分隔符的规则. 指定为以下值之一：
        - "split": 将连续分隔符拆分多个字段;
        - "join": 将多个分隔符合并成一个分隔符.
    默认值为 "split".
    LeadingDelimitersRule: 管理前导分隔符的规则. 指定为以下指之一:
        - "keep": 保留分隔符;
        - "ignore": 忽略分隔符.
    默认值为 "keep".
    NumHeaderLines: 标题行数. 默认值为 0.
)";

static bexfun_info_t flist [] = {
    {"getmatrix", getmatrix, getmatrix_help},
    {"", nullptr, nullptr}, // 表示列表结尾
};

bexfun_info_t *bxPluginFunctions(){
    return flist;
}

/* 常见内函数的具体实现 */
void getmatrix(int nlhs, bxArray *plhs[], int nrhs, const bxArray *prhs[]){
    // 检查输入参数个数
    if (nrhs < 1) {
        // bxErrMsgTxt(const char*) 终止当前函数调用并向图形界面或命令行窗口输出错误信息
        bxErrMsgTxt("输入参数的数目不足!");
    }
    if (nrhs % 2 == 0) {
        bxErrMsgTxt("所有参数都必须具有关联的值!");
    }

    // 默认参数
    std::string delimiter = " ";            // 分隔符
    bool consecutive = false;               // 将连续分隔符视为单个分隔符
    bool ignore = false;                    // 忽略行首分隔符
    uint8_t num_header_lines = 0;           // 表头行数
    // 解析输入参数
    std::string filename = GetFileName(prhs[0]);
    for (int i = 1; i < nrhs; i += 2) {
        std::string parameter = GetParameterName(prhs[i]);
        if (parameter == "delimiter") {
            delimiter = baltam::bxAsString(prhs[i + 1]);
        } else if (parameter == "consecutivedelimitersrule") {
            consecutive = GetConsecutive(prhs[i + 1]);
        } else if (parameter == "leadingdelimitersrule") {
            ignore = GetLeadingRule(prhs[i + 1]);
        } else if (parameter == "numheaderlines") {
            num_header_lines = GetNumHeaderLines(prhs[i + 1]);
        } else {
            std::string info = "未知参数 '" + parameter + "'!";
            bxErrMsgTxt(info.c_str());
        }
    }

    plhs[0] = readdata(filename, delimiter, ignore, consecutive, num_header_lines);

    return;
}
